package com.talios.jira.settings;

import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.IconLoader;
import com.talios.jira.browser.ColumnMetaInfo;
import com.talios.jira.browser.ColumnSetting;
import com.talios.jira.browser.signals.JiraServerDetails;
import com.talios.jira.idea.JiraConfiguration;
import com.talios.jira.idea.JiraConfigurationComponent;

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/**
 * Created by IntelliJ IDEA.
 * User: amrk
 * Date: 22/01/2004
 * Time: 07:57:55
 * To change this template use File | Settings | File Templates.
 */
public class SettingsForm {
    private JPanel mainPanel;
    private JCheckBox enableIssueTracking;
    private JTextField projectId;

    private Project project;
    private JCheckBox autoRefresh;
    private JCheckBox useExternalBrowser;
    private JSpinner refreshTimeout;
    private JPanel projectToolPanel;
    private JTable serversTable;
    private JiraServerDetails server;
    private JiraConfiguration config;
    private JCheckBox annotate;
    private JPanel propertiesPanel;
    private JPanel serversPanel;
    private boolean serversUpated;
    private boolean columnsUpdated;
    private JTabbedPane tabbedPane1;
    private JTable columnsTable;
    private JPanel columnsToolPanel;

    public SettingsForm(Project project) {
        this.project = project;
        config = project.getComponent(JiraConfigurationComponent.class).getConfiguration();

        enableIssueTracking.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent event) {
                boolean b = event.getStateChange() == ItemEvent.SELECTED;

                setSettingsEnabled(b);
            }

        });


        refreshTimeout.setModel(new SpinnerNumberModel(60, 0, 120, 5));


        ActionManager actionManager = ActionManager.getInstance();
        DefaultActionGroup serverActionGroup = new DefaultActionGroup();
        DefaultActionGroup columnActionGroup = new DefaultActionGroup();

        serverActionGroup.add(new AddServerAction());
        serverActionGroup.add(new RemoveServerAction());

        columnActionGroup.add(new AddColumnAction());
        columnActionGroup.add(new RemoveColumnAction());

        ActionToolbar viewToolbar = actionManager.createActionToolbar("JIRA.ServersToolbar", serverActionGroup, false);
        ActionToolbar columnToolbar = actionManager.createActionToolbar("JIRA.ColumnToolbar", columnActionGroup, false);

        projectToolPanel.add(viewToolbar.getComponent());
        columnsToolPanel.add(columnToolbar.getComponent());

        serversTable.setModel(new ServersTableModel(project));

        serversTable.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent mouseEvent) {
                if (mouseEvent.getClickCount() == 2 && mouseEvent.getButton() == MouseEvent.BUTTON1 && serversTable.isEnabled()) {
                    new EditServerAction().actionPerformed(null);
                }
            }
        });

        columnsTable.setModel(new ColumnsTableModel(project));

        ServerCellRenderer renderer = new ServerCellRenderer();
        for (int i = 0; i < serversTable.getColumnModel().getColumnCount(); i++) {
            TableColumn column = serversTable.getColumnModel().getColumn(i);
            column.setCellRenderer(renderer);
        }

    }

    public void setData(JiraConfiguration data) {
        enableIssueTracking.setSelected(data.getEnableIssueTracking());
        useExternalBrowser.setSelected(data.getUseExternalBrowser());
        autoRefresh.setSelected(data.getAutoRefresh());
        annotate.setSelected(data.getAnnotateIssues());
        refreshTimeout.getModel().setValue(data.getRefreshTimeout());
    }

    public void getData(JiraConfiguration data) {
        data.setEnableIssueTracking(enableIssueTracking.isSelected());
        data.setUseExternalBrowser(useExternalBrowser.isSelected());
        data.setAutoRefresh(autoRefresh.isSelected());
        data.setAnnotateIssues(annotate.isSelected());

        data.setRefreshTimeout(((SpinnerNumberModel) refreshTimeout.getModel()).getNumber().intValue());
    }

    public boolean isModified(JiraConfiguration data) {
        if (enableIssueTracking.isSelected() != data.getEnableIssueTracking()) return true;
        if (useExternalBrowser.isSelected() != data.getUseExternalBrowser()) return true;
        if (autoRefresh.isSelected() != data.getAutoRefresh()) return true;
        if (annotate.isSelected() != data.getAnnotateIssues()) return true;
        if (serversUpated) return true;
        if (columnsUpdated) return true;
        return ((SpinnerNumberModel) refreshTimeout.getModel()).getNumber().intValue() != data.getRefreshTimeout();
    }

    public class ServerCellRenderer extends DefaultTableCellRenderer {
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            component.setForeground(enableIssueTracking.isSelected() ? Color.BLACK : Color.GRAY);
            return component;
        }
    }

    public void setSettingsEnabled(boolean b) {
        toggleEnabledForChildren(propertiesPanel, b);
        toggleEnabledForChildren(tabbedPane1, b);
    }

    private void toggleEnabledForChildren(JComponent component, boolean b) {
        component.setEnabled(b);
        Component[] childComponents = component.getComponents();
        for (Component childComponent : childComponents) {
            childComponent.setEnabled(b);
            if (childComponent instanceof JComponent) {
                toggleEnabledForChildren((JComponent) childComponent, b);
            }
        }
    }


    public JPanel getMainPanel() {
        return mainPanel;
    }

    public JTextField getProjectId() {
        return projectId;
    }

    public void setProjectId(JTextField projectId) {
        this.projectId = projectId;
    }

    public JCheckBox getEnableIssueTracking() {
        return enableIssueTracking;
    }

    public void setEnableIssueTracking(JCheckBox enableIssueTracking) {
        this.enableIssueTracking = enableIssueTracking;
    }

    public JCheckBox getAutoRefresh() {
        return autoRefresh;
    }

    public void setAutoRefresh(JCheckBox autoRefresh) {
        this.autoRefresh = autoRefresh;
    }

    public JCheckBox getUseExternalBrowser() {
        return useExternalBrowser;
    }

    public void setUseExternalBrowser(JCheckBox useExternalBrowser) {
        this.useExternalBrowser = useExternalBrowser;
    }

    public JCheckBox getAnnotateIssues() {
        return annotate;
    }

    public void setAnnotate(JCheckBox annotate) {
        this.annotate = annotate;
    }

    public JSpinner getRefreshTimeout() {
        return refreshTimeout;
    }

    public void setRefreshTimeout(JSpinner refreshTimeout) {
        this.refreshTimeout = refreshTimeout;
    }

    private class AddColumnAction extends AnAction {
        public AddColumnAction() {
            super("Add", "Add Column", IconLoader.getIcon("/general/add.png"));
        }

        public void actionPerformed(AnActionEvent anActionEvent) {
            // TODO Add a fixed field for now, then add prompting...


            String s = (String) JOptionPane.showInputDialog(null,
                    "Select a Column:",
                    "JIRA",
                    JOptionPane.PLAIN_MESSAGE,
                    IconLoader.getIcon("/general/add.png"),
                    ColumnMetaInfo.getColumnKeys(),
                    "title");

            if (s != null && s.length() > 0) {
                ColumnSetting columnSetting = new ColumnSetting(s,
                        config.getColumnList().size() + 1,
                        -1);

                ColumnsTableModel columnsModel = (ColumnsTableModel) columnsTable.getModel();
                config.getColumnList().add(columnSetting);
                columnsModel.fireTableDataChanged();
                columnsUpdated = true;
            }
        }
    }

    private class RemoveColumnAction extends AnAction {
        public RemoveColumnAction() {
            super("Remove", "Remove Column", IconLoader.getIcon("/general/remove.png"));
        }

        public void actionPerformed(AnActionEvent anActionEvent) {
            if (Messages.showYesNoDialog(project, "Remove Selected Column?", "JIRA", IconLoader.getIcon("/general/remove.png")) == JOptionPane.YES_OPTION) {
                ColumnsTableModel columnsModel = (ColumnsTableModel) columnsTable.getModel();
                ColumnSetting columnSetting = columnsModel.getColumnSetting(columnsTable.getSelectedRow());
                config.getColumnList().remove(columnSetting);
                columnsModel.fireTableDataChanged();
                columnsUpdated = true;
            }
        }

        public void update(AnActionEvent event) {
            event.getPresentation().setEnabled(enableIssueTracking.isSelected() && columnsTable.getSelectedRowCount() != 0);
        }

    }


    private class AddServerAction extends AnAction {
        public AddServerAction() {
            super("Add", "Add Server", IconLoader.getIcon("/general/add.png"));
        }

        public void actionPerformed(AnActionEvent event) {
            JiraServerDetails newServer = new JiraServerDetails();
            ServerDetails serverDetails = new ServerDetails(project, "Add Server");
            ServersTableModel serversModel = (ServersTableModel) serversTable.getModel();

            newServer.setUseCustomDateFormat(false);
            newServer.setSupportLegacy(false);

            if (serverDetails.editServerDetails(newServer) != null) {
                config.getServerList().add(newServer);
                serversModel.fireTableDataChanged();
                serversUpated = true;
            }
        }

        public void update(AnActionEvent event) {
            event.getPresentation().setEnabled(enableIssueTracking.isSelected());
        }
    }

    private class EditServerAction extends AnAction {
        public EditServerAction() {
            super("Edit", "Edit Server", IconLoader.getIcon("/general/configurableEditor.png"));
        }

        public void actionPerformed(AnActionEvent event) {
            ServersTableModel serversModel = (ServersTableModel) serversTable.getModel();
            JiraServerDetails server = serversModel.getServer(serversTable.getSelectedRow());
            ServerDetails serverDetails = new ServerDetails(project, "Edit Server");
            serverDetails.editServerDetails(server);
            serversModel.fireTableDataChanged();
            serversUpated = true;
        }
    }

    private class RemoveServerAction extends AnAction {
        public RemoveServerAction() {
            super("Remove", "Remove Server", IconLoader.getIcon("/general/remove.png"));
        }

        public void actionPerformed(AnActionEvent event) {
            if (Messages.showYesNoDialog(project, "Remove Selected Server?", "JIRA", IconLoader.getIcon("/general/remove.png")) == JOptionPane.YES_OPTION) {
                ServersTableModel serversModel = (ServersTableModel) serversTable.getModel();
                JiraServerDetails server = serversModel.getServer(serversTable.getSelectedRow());
                config.getServerList().remove(server);
                serversModel.fireTableDataChanged();
                serversUpated = true;
            }
        }

        public void update(AnActionEvent event) {
            event.getPresentation().setEnabled(enableIssueTracking.isSelected() && serversTable.getSelectedRowCount() != 0);
        }

    }
}
